let EIndex = function () {
    let currentUser = null;
    let rootId = '0'; // 根菜单id

    // 第一次加载消息
    let isFirstLoadMessage = true;
    /**
     * 上次查询消息时的未读消息数量
     * 如此数量未发生变化就算有未读消息也不刷新消息列表
     * @type {number}
     */
    let lastSelectUnreadMessageCount = 0;

    /**
     * 加载菜单
     *
     * @param keepVarMenu {boolean} 是否保持垂直方向菜单不变 eg: true/false
     */
    let loadMenu = function (keepVarMenu) {
        let menus = currentUser.menus;
        if (typeof menus !== 'undefined') {
            // 水平菜单
            let $horizontalMenu = $('#header-menu > ul').empty();
            // 侧边菜单
            let $varMenu = $('#aside-menu');

            if (menus.length > 0) {
                menus = objectToArray(buildTree(menus));
                if (preferenceSettings.enableHorizontalMenu()) {
                    // 初始化水平方向菜单
                    $horizontalMenu.html(initHorizontalMenu(menus));
                    if (!keepVarMenu) {
                        // 初始化侧边菜单
                        $varMenu.html(initVarMenu(menus));
                    }
                } else {
                    let $menuNav = $varMenu.html('<ul class="e-menu-nav"></ul>').find('ul');
                    // 初始化侧边菜单
                    $menuNav.append(initMenu(menus, true));
                }
            } else {
                $varMenu.html(
                    '<ul class="e-menu-nav">\
                               <li class="e-menu-section ">\
                                   <h4 class="e-menu-section-text">用户暂无菜单</h4>\
                                   <i class="e-menu-section-icon flaticon-more-v2"></i>\
                               </li>\
                           </ul>'
                );
            }
            setDefaultHorMenu();
        }
    };
    /**
     * 获取水平方向菜单
     * 如果宽度超过ul，需折叠
     *
     * @param menus {array} 菜单
     * @returns {string} html
     */
    let initHorizontalMenu = function (menus) {
        // 容器宽度
        let $horizontalMenu = $('#header-menu > ul'),
            $header = $('#header');
        let wrapWidth = $header.width() - $header.find('.e-header-topbar').outerWidth();
        // margin + 下拉按钮宽度
        let dropdownWidth = 85;
        // 展开的按钮可用宽度
        let expandButtonWidth = wrapWidth - dropdownWidth;
        let totalWidth = 0;
        /**
         * 计算单个菜单占用宽度
         *
         * @param menu {object} 菜单
         * @returns {*}
         */
        let calcWidth = function (menu) {
            $horizontalMenu.empty().append(
                '<li class="e-menu-item e-menu-item--rel" style="visibility: hidden">\
                    <a data-target="#sub-menu-' + menu.id + '" href="javascript:;" class="e-menu-link">' + getMenuIcon(menu, true) + getMenuText(menu) + '</a>\
                </li>'
            );
            return $horizontalMenu.outerWidth();
        };

        let expandMenuLi = '',
            dropdownMenuLi = '',
            html;
        $(menus).each(function (index, menu) {
            // 累加宽度
            totalWidth += calcWidth(menu);
            if (totalWidth < expandButtonWidth) {
                expandMenuLi += '\
                <li class="e-menu-item e-menu-item--rel">\
                    <a data-target="#sub-menu-' + menu.id + '" href="#" class="e-menu-link">' + getMenuIcon(menu, true) + getMenuText(menu) + '</a>\
                </li>';
            } else {
                // 将菜单收起到dropdown中
                dropdownMenuLi += '\
                    <li class="e-nav-item">\
                        <a class="e-nav-link" data-toggle="tab" href="#" data-target="#sub-menu-' + menu.id + '">\
                            <span class="e-menu-link-icon">' + getMenuIcon(menu, true) + '</span>\
                            <span class="e-nav-link-text">' + getMenuText(menu) + '</span>\
                        </a>\
                    </li>\
                    ';
            }
        });
        html = expandMenuLi;

        if (EUtil.isNotBlank(dropdownMenuLi)) {
            html += '\
                <li class="e-menu-item e-menu-item--rel e-menu-item-more">\
                    <a href="javascript:;" class="e-menu-link dropdown-toggle" data-toggle="dropdown">\
                        <span class="e-menu-link-icon">\
                            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" class="e-svg-icon">\
                                <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\
                                    <rect id="bound" x="0" y="0" width="24" height="24"></rect>\
                                    <circle id="Oval-67" fill="#000000" cx="12" cy="5" r="2"></circle>\
                                    <circle id="Oval-67-Copy" fill="#000000" cx="12" cy="12" r="2"></circle>\
                                    <circle id="Oval-67-Copy-2" fill="#000000" cx="12" cy="19" r="2"></circle>\
                                </g>\
                            </svg>\
                        </span>\
                    </a>\
                    <div class="dropdown-menu">\
                        <ul class="e-nav" role="tablist">' + dropdownMenuLi + '</ul>\
                    </div>\
                </li>';
        }
        return html;
    };

    /**
     * 获取侧边菜单
     *
     * @param menus {array} 菜单
     * @returns {string} html
     */
    let initVarMenu = function (menus) {
        let html = '';
        $(menus).each(function (index, menu) {
            if (typeof menu.children !== 'undefined') {
                html += '<ul id="sub-menu-' + menu.id + '" style="display: none;" class="e-menu-nav">' + initMenu(menu.children, true) + '</ul>';
            }
        });
        return html;
    };
    /**
     * 将一维的扁平数组转换为多层级对象
     * @param  {array} list 一维数组，数组中每一个元素需包含id和pId两个属性
     * @return {object} tree 多层级树状结构
     */
    let buildTree = function (list) {
        let temp = {};
        let tree = {};
        for (let i in list) {
            temp[list[i].id] = list[i];
        }
        for (let i in temp) {
            // 不是根菜单&&没有父菜单
            if (temp[i].pId !== rootId && temp[temp[i].pId]) {
                if (!temp[temp[i].pId].children) {
                    temp[temp[i].pId].children = {};
                }
                temp[temp[i].pId].children[temp[i].id] = temp[i];
            } else {
                tree[temp[i].id] = temp[i];
            }
        }
        return tree;
    };
    /**
     * 获取菜单html
     *
     * @param menus {object} 菜单
     * @param isBase {boolean} 是否是一级菜单
     * @returns {string} html
     */
    let initMenu = function (menus, isBase) {
        let _html = '';
        $(objectToArray(menus)).each(function (i, menu) {
            _html += getMenuHtml(menu, isBase);
        });
        return _html;
    };
    /**
     * 将object菜单转为array并排序
     *
     * @param menus
     * @returns {*}
     */
    let objectToArray = function (menus) {
        let array = Object.values(menus);
        array.sort(function (a, b) {
            return a.orderNo - b.orderNo
        });
        return array;
    };
    /**
     * 获取菜单图标
     *
     * @param menu {object} 菜单
     * @param isBase {boolean} 是否是一级菜单
     * @returns {string}
     */
    let getMenuIcon = function (menu, isBase) {
        if (isBase) {
            return '<span class="e-menu-link-icon">' + menu.icon + '</span>';
        } else {
            return '<i class="e-menu-link-bullet e-menu-link-bullet--dot"><span></span></i>';
        }
    };
    /**
     * 获取菜单文字
     *
     * @param menu {object} 菜单
     * @returns {string} html
     */
    let getMenuText = function (menu) {
        return '<span class="e-menu-link-text">' + menu.name + '</span>';
    };
    /**
     * 获取菜单url
     *
     * @param menu {object} 菜单
     * @returns {string} url
     */
    let getMenuUrl = function (menu) {
        return (1 === menu.isExternalLinks ? '' : basePath) + (EUtil.isNotBlank(menu.url) ? menu.url : '');
    };
    /**
     * 检查是否有子菜单
     *
     * @param submenu {object} 子菜单
     * @returns {boolean}
     */
    let hasSubMenu = function (submenu) {
        return typeof submenu !== 'undefined';
    };
    /**
     * 获取菜单链接
     *
     * @param content {string} 链接内容
     * @param menu {object} 菜单
     * @returns {string} html
     */
    let getMenuLink = function (content, menu) {
        return '<a class="e-menu-link ' + (hasSubMenu(menu.children) ? 'e-menu-toggle' : '') + '" href="' + getMenuUrl(menu) + '">' + content + '</a>';
    };
    /**
     * 获取菜单html代码
     *
     * @param menu {object} 菜单对象
     * @param isBase {boolean} 是否是一级菜单
     * @returns {string} html
     */
    let getMenuHtml = function (menu, isBase) {
        let menuArrow = '<i class="e-menu-ver-arrow la la-angle-right"></i>';
        if (typeof menu !== 'undefined') {
            let _html = '<li class="e-menu-item ' + (hasSubMenu(menu.children) ? 'e-menu-item--submenu' : '') + '">';
            if (hasSubMenu(menu.children)) {
                _html += getMenuLink(getMenuIcon(menu, isBase) + getMenuText(menu) + menuArrow, menu) +
                    '<div class="e-menu-submenu ">\
                        <span class="e-menu-arrow"></span>\
                        <ul class="e-menu-subnav">' + initMenu(menu.children, false) + '</ul>\
                    </div>';
            } else {
                if (isBase) {
                    _html += getMenuLink(
                        getMenuIcon(menu, isBase) +
                        '<span class="e-menu-link-text">\
                            ' + getMenuText(menu) + '\
                        </span>'
                        , menu);
                } else {
                    _html += getMenuLink(getMenuIcon(menu, isBase) + getMenuText(menu), menu);
                }
            }
            return _html + '</li>';
        } else {
            return '';
        }
    };
    // 横向菜单选择器
    let hroMenuSelector = '.e-menu-item:not(.e-menu-item-more) > .e-menu-link:not(.e-menu-toggle):not(.e-menu-link--toggle-skip), .e-menu-item-more .e-nav-link';
    /**
     * 横向菜单点击事件
     *
     * @param $menu
     */
    let horMenuClick = function ($menu) {
        $('#header-menu').find(hroMenuSelector).parent().removeClass('active');
        $menu.parent().addClass('active');
        let target = $menu.data('target');
        let $target = $(target);
        if ($target.length > 0) {
            // 放到缓存里刷新页面后自动选中上次选中项
            ETool.setCache('hor-menu', target);
            // 有目标子菜单
            $('#aside-menu').children('ul').hide();
            $target.show();
            EApp.animateCSS(target, EApp.getAnimate('in'), null);
        } else {
            EApp.openPage($menu.text(), $menu.data('url'));
        }
    };
    /**
     * 设置默认横向水平菜单选中项
     */
    let setDefaultHorMenu = function () {
        let target = ETool.getCache('hor-menu');
        let $menu;
        if (EUtil.isNotBlank(target)) {
            let _menu = $('[data-target="' + target + '"]');
            if (_menu.length > 0) {
                // 如果缓存里有选中的
                $menu = _menu;
            }
        }
        if ($menu == null) {
            $menu = $('#header-menu > ul > li:nth-child(1) > a');
        }
        horMenuClick($menu);
    };
    /**
     * 添加点击链接事件
     */
    let bindLinkClick = function () {
        // 横向菜单
        $('#header-menu').on('click', hroMenuSelector, function (e) {
            e.preventDefault();
            horMenuClick($(this));
        });
        // 侧边菜单
        ELayout.getAsideMenu().on('linkClick', function (menu, a) {
            let $menu = $(a);
            let url = $menu.attr('href');
            if (EUtil.isBlank(url) || '#' === url || basePath === url) {
                url = basePath + '/global/in-development';
            }
            EApp.openPage($menu.text(), url);
        });
    };

    /**
     * 处理常规按钮的点击事件
     */
    let bindGeneralLinkClick = function () {
        $('body').on('click', '.e-tab-page-link', function (e) {
            e.preventDefault();
            let $link = $(this);
            let url = $link.attr('href');
            EApp.openPage($link.text(), url);
        });
    };

    /**
     * 消息图标
     */
    let messageIcon = {
        read: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" class="e-svg-icon e-svg-icon-invalid">\n' +
            '    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n' +
            '        <rect id="bound" x="0" y="0" width="24" height="24"/>\n' +
            '        <path d="M6,2 L18,2 C18.5522847,2 19,2.44771525 19,3 L19,12 C19,12.5522847 18.5522847,13 18,13 L6,13 C5.44771525,13 5,12.5522847 5,12 L5,3 C5,2.44771525 5.44771525,2 6,2 Z M7.5,5 C7.22385763,5 7,5.22385763 7,5.5 C7,5.77614237 7.22385763,6 7.5,6 L13.5,6 C13.7761424,6 14,5.77614237 14,5.5 C14,5.22385763 13.7761424,5 13.5,5 L7.5,5 Z M7.5,7 C7.22385763,7 7,7.22385763 7,7.5 C7,7.77614237 7.22385763,8 7.5,8 L10.5,8 C10.7761424,8 11,7.77614237 11,7.5 C11,7.22385763 10.7761424,7 10.5,7 L7.5,7 Z" id="Combined-Shape" fill="#000000" opacity="0.3"/>\n' +
            '        <path d="M3.79274528,6.57253826 L12,12.5 L20.2072547,6.57253826 C20.4311176,6.4108595 20.7436609,6.46126971 20.9053396,6.68513259 C20.9668779,6.77033951 21,6.87277228 21,6.97787787 L21,17 C21,18.1045695 20.1045695,19 19,19 L5,19 C3.8954305,19 3,18.1045695 3,17 L3,6.97787787 C3,6.70173549 3.22385763,6.47787787 3.5,6.47787787 C3.60510559,6.47787787 3.70753836,6.51099993 3.79274528,6.57253826 Z" id="Combined-Shape" fill="#000000"/>\n' +
            '    </g>\n' +
            '</svg>',
        unread: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" class="e-svg-icon">\n' +
            '    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n' +
            '        <rect id="bound" x="0" y="0" width="24" height="24"/>\n' +
            '        <path d="M5,6 L19,6 C20.1045695,6 21,6.8954305 21,8 L21,17 C21,18.1045695 20.1045695,19 19,19 L5,19 C3.8954305,19 3,18.1045695 3,17 L3,8 C3,6.8954305 3.8954305,6 5,6 Z M18.1444251,7.83964668 L12,11.1481833 L5.85557487,7.83964668 C5.4908718,7.6432681 5.03602525,7.77972206 4.83964668,8.14442513 C4.6432681,8.5091282 4.77972206,8.96397475 5.14442513,9.16035332 L11.6444251,12.6603533 C11.8664074,12.7798822 12.1335926,12.7798822 12.3555749,12.6603533 L18.8555749,9.16035332 C19.2202779,8.96397475 19.3567319,8.5091282 19.1603533,8.14442513 C18.9639747,7.77972206 18.5091282,7.6432681 18.1444251,7.83964668 Z" id="Combined-Shape" fill="#000000"/>\n' +
            '    </g>\n' +
            '</svg>'
    };

    /**
     * 消息
     */
    let sysMessage = function () {
        // 每种类型最多只显示20条
        let size = 20;

        /**
         * 获取消息
         */
        let selectMessage = function () {
            EUtil.ajax({
                url: basePath + '/auth/sys/message/select/receive',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify({
                    ignore: 1,
                    page: {
                        size: size
                    }
                }),
                success: function (res) {
                    let $container = $('#sys-message');
                    $container.empty();
                    if (res.data.records.length > 0) {
                        $(res.data.records).each(function (index, message) {
                            $container.append(
                                '<a href="javascript:;" data-url="' + basePath + '/auth/sys/message/info/' + message.messageId + '/' + message.id + '" class="e-notification-item">\
                                    <div class="e-notification-item-icon">\
                                    ' + (message.readDate ? messageIcon.read : messageIcon.unread) + '\
                                    </div>\
                                    <div class="e-notification-item-details">\
                                        <div class="e-notification-item-title ' + (message.readDate ? '' : ' unread') + '">\
                                            ' + message.title + '\
                                        </div>\
                                        <div class="e-notification-item-time" title="' + message.sendDate + '">\
                                            ' + (moment(message.sendDate, 'YYYY-MM-DD HH:mm:ss').fromNow()) + '\
                                        </div>\
                                    </div>\
                                </a>'
                            )
                        });
                    } else {
                        $container.html(
                            '<div class="e-grid e-grid--ver" style="min-height: 200px;">\
                                <div class="e-grid e-grid--hor e-grid-item e-grid-item--fluid e-grid-item--middle">\
                                    <div class="e-grid-item e-grid-item--middle e-align-center">\
                                        暂无消息\
                                    </div>\
                                </div>\
                            </div>'
                        );
                    }
                }
            });
        };

        /**
         * 加载消息
         */
        let loadMessage = function () {
            selectMessage();
        };
        /**
         * 获取当前登录用户查询未读消息数量
         */
        let selectUnreadCount = function () {
            EUtil.ajax({
                url: basePath + '/auth/sys/message/select/unread/count',
                data: {
                    ignore: 1
                },
                success: function (res) {
                    if (lastSelectUnreadMessageCount !== res.data || isFirstLoadMessage) {
                        // 记录上次更新消息时的未读消息数量
                        lastSelectUnreadMessageCount = res.data;
                        isFirstLoadMessage = false;
                        // 有新消息,刷新消息列表
                        loadMessage();
                        // 更新消息提示
                        $('.unread-count').html(res.data);
                        if (res.data > 0) {
                            $('.new-message-tip, .unread-count').removeClass('e-hide');
                        } else {
                            $('.new-message-tip, .unread-count').addClass('e-hide');
                        }
                    }
                }
            });
        };
        return {
            /**
             * 检查消息是否需要更新,如果需要则刷新
             */
            selectUnreadCount: function () {
                selectUnreadCount();
            }
        }
    }();

    /**
     * 读消息
     *
     * @param element {object} 消息链接
     */
    let readMessage = function (element) {
        let $link = $(element);
        // 移除未读class
        $link.find('.e-notification-item-title').removeClass('unread');
        // 更改消息图标
        $link.find('.e-notification-item-icon').html(messageIcon.read);
        // 打开页面
        EApp.openPage($link.text(), $link.data('url'));
    };
    /**
     * 给消息绑定事件
     */
    let bindMessage = function () {
        $('.message-container').on('click', '[data-url]', function () {
            readMessage(this);
        });
    };

    /**
     * 用户偏好设置
     */
    let preferenceSettings = function () {
        // 缓存中的key
        let cacheKey = 'preference-settings';

        // 皮肤文件根目录
        let baseSkinsPath = basePath + '/static/themes/theme-1/css/skins/';

        /**
         * 获取设置
         *
         * @return {object} 偏好设置
         */
        let getSettings = function () {
            return $('.preference-settings').serializeObject();
        };
        /**
         * 应用设置
         *
         * @param settings {object} 配置项
         * @param update {boolean} 是否更新缓存配置
         */
        let setSettings = function (settings, update) {
            let oldEnableHorizontalMenu = preferenceSettings.enableHorizontalMenu();
            if (update) {
                ETool.setCache(cacheKey, settings);
            }
            if (settings != null) {
                updateCheckbox(settings);
                updateSkins(settings);
                // 设置菜单收起/展开状态
                setAsideMin(settings.pickUpTheMenu);
                // 隐藏footer
                if (settings.hideFooter) {
                    $('body').addClass('hide-footer');
                } else {
                    $('body').removeClass('hide-footer');
                }

                // 检查水平方向菜单配置是否发生更改
                if (settings.enableHorizontalMenu !== oldEnableHorizontalMenu) {
                    // 如果发生更改了,则更新菜单
                    loadMenu(false);
                }
                if (settings.enableHorizontalMenu) {
                    EUtil.addResizeHandler(EIndex.windowResizeMenuHandle);
                } else {
                    EUtil.removeResizeHandler(EIndex.windowResizeMenuHandle);
                }
            }
        };
        /**
         * 应用皮肤
         *
         * @param settings {object} 配置项
         */
        let updateSkins = function (settings) {
            let skinsHeaderBase = $('#skins-header-base');
            let skinsHeaderMenu = $('#skins-header-menu');
            let skinsBrand = $('#skins-brand');
            let skinsAside = $('#skins-aside');

            if (settings.darkHead) {
                // 启用暗色头部
                skinsHeaderBase.attr('href', baseSkinsPath + 'header/base/dark' + staticMin + '.css');
                skinsHeaderMenu.attr('href', baseSkinsPath + 'header/menu/dark' + staticMin + '.css');
            } else {
                skinsHeaderBase.attr('href', baseSkinsPath + 'header/base/light' + staticMin + '.css');
                skinsHeaderMenu.attr('href', baseSkinsPath + 'header/menu/light' + staticMin + '.css');
            }

            if (settings.darkBrand) {
                skinsBrand.attr('href', baseSkinsPath + 'brand/dark' + staticMin + '.css');
            } else {
                skinsBrand.attr('href', baseSkinsPath + 'brand/light' + staticMin + '.css');
            }

            if (settings.darkAside) {
                // 启用暗色侧边
                skinsAside.attr('href', baseSkinsPath + 'aside/dark' + staticMin + '.css');
            } else {
                skinsAside.attr('href', baseSkinsPath + 'aside/light' + staticMin + '.css');
            }
        };
        /**
         * 更改checkbox状态
         *
         * @param settings {object} 配置
         */
        let updateCheckbox = function (settings) {
            $('.preference-settings').find('input[type="checkbox"]:not([disabled])').each(function () {
                let $checkbox = $(this);
                if (settings[$checkbox.attr('name')]) {
                    $checkbox.prop('checked', true);
                } else {
                    $checkbox.prop('checked', false);
                }
            });
        };
        /**
         * 设置左侧菜单收起状态
         *
         * @param pickUp {boolean} eg: true=收起、false=展开
         */
        let setAsideMin = function (pickUp) {
            if (pickUp) {
                $('body').addClass('e-aside--minimize');
                $('#aside-toggler').addClass('active');
            } else {
                $('body').removeClass('e-aside--minimize');
                $('#aside-toggler').removeClass('active');
            }
        };
        return {
            /**
             * 初始化
             */
            init: function () {
                // 应用当前用户设置
                let settings = preferenceSettings.getPreferenceSettings();
                if (settings) {
                    setSettings(settings, false);
                }
                // 绑定更改偏好设置事件
                $('.preference-settings').find('input[type="checkbox"]').change(function () {
                    setSettings(getSettings(), true);
                });
            },
            /**
             * 获取缓存中的配置
             * @return {object} 配置
             */
            getPreferenceSettings: function () {
                let cacheSettings = ETool.getCache(cacheKey);
                let settings = null;
                if (EUtil.isNotBlank(cacheSettings)) {
                    settings = $.parseJSON(cacheSettings);
                }
                return settings
            },
            /**
             * 是否启用横向菜单
             *
             * @return {boolean} true/false
             */
            enableHorizontalMenu: function () {
                let enableHorizontalMenu = true;
                let settings = preferenceSettings.getPreferenceSettings();
                if (settings) {
                    enableHorizontalMenu = settings.enableHorizontalMenu;
                }
                return enableHorizontalMenu;
            }
        };
    }();

    return {
        init: function () {
            // 初始化偏好设置
            preferenceSettings.init();
            // 更新缓存中的当前登录用户
            currentUser = ETool.getUser(false);

            // 加载菜单
            loadMenu(false);
            // 设置上次选中的水平方向菜单
            setDefaultHorMenu();
            // 绑定菜单点击事件
            bindLinkClick();
            // 常规按钮点击事件
            bindGeneralLinkClick();

            // 初始化消息定时检查
            setInterval(sysMessage.selectUnreadCount, messageCheckInterval);
            // 页面加载完后马上查询一次消息
            sysMessage.selectUnreadCount();
            // 给消息绑定事件
            bindMessage();
        },
        /**
         * 当窗口大小发生变动时，需要重新设置水平方向菜单，以免菜单文字换行
         */
        windowResizeMenuHandle: function () {
            console.log('重新设置菜单');
            loadMenu(true);
        }
    }
}();
$(document).ready(function () {
    EIndex.init();
});